package com.ultron.core.component.excel;//
// Created by  on 2021/3/30.
//

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 原子操作型缓存工具
 * @param <T>
 * @param <K>
 */
public class CacheUtil<T, K> {
    private final Map<K, T> map = new ConcurrentHashMap<>();
    /**
     * 定时清理。
     */
    long timeout;
    TimeUnit unit;
    private ICallBack<T, K> callBack;
    private int max;
    private ScheduledExecutorService scheduledExecutorService;

    /**
     * 定时清理
     *
     * @param timeout 单位S
     */
    public CacheUtil(int timeout, TimeUnit unit) {
        this.timeout = timeout;
        this.unit=unit;
        clearWhenTimeOut();
    }

    /**
     * 定时清理
     *
     * @param timeout 单位S
     */
    public CacheUtil(int timeout, ICallBack<T, K> callBack) {
        this.timeout = timeout;
        clearWhenTimeOut();
        this.callBack = callBack;
    }

    public CacheUtil() {

    }

    private void clearWhenTimeOut() {
        if (timeout == 0) {
            return;
        }
        if (scheduledExecutorService != null) {
            try {
                scheduledExecutorService.shutdownNow();
            } catch (Exception ignored) {

            }
        }
        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.schedule(() -> {
            if (map.size() > 0) {
                System.out.println(map + "到期清理了");
                if (callBack != null) {
                    callBack.onTimeOut(map);
                }
                map.clear();
            }
        }, timeout, unit);
    }

    /**
     * 本地缓存
     */
    public T getValue(K key) {
        return map.get(key);
    }

    /**
     * 带默认值
     */
    public T getValue(K key, T v) {
        return map.getOrDefault(key, v);
    }

    public void updateValue(K key, T value) {
        map.put(key, value);
        clearWhenTimeOut();
    }

    public Map<K, T> getCaheMap() {
        return map;
    }

    public Collection<T> getValues() {
        return map.values();
    }

    public void remove(K sn) {
        map.remove(sn);
    }


    public void clear() {
        map.clear();
    }

    public interface ICallBack<T, K> {
        void onTimeOut(Map<K, T> map);
    }


}
